#!/usr/bin/perl

use Test;

BEGIN {
    $basedir = $0;
    $basedir =~ s|(.*)/[^/]*|$1|;

    $test_count = 8;
    $socketpair = 0;

    $kvercur = `uname -r`;
    chomp($kvercur);

    # Test SO_PEERSEC for sockets created by socketpair(2).
    $kverminstream = "4.18";
    $result        = `$basedir/../kvercmp $kvercur $kverminstream`;
    if ( $result >= 0 ) {
        $test_count += 2;
        $socketpair = 1;
    }

    plan tests => $test_count;
}

#
# Tests for sockets in the abstract namespace.
#

sub server_start {
    my ( $runcon_args, $args ) = @_;
    my $pid;

    system("mkfifo $basedir/flag");

    if ( ( $pid = fork() ) == 0 ) {
        exec "runcon $runcon_args $basedir/server -f $basedir/flag $args";
    }

    # Wait for it to initialize.
    system("read -t 5 <>$basedir/flag");
    return $pid;
}

sub server_end {
    my ($pid) = @_;

    kill KILL, $pid;
    waitpid $pid, 0;
    system("rm -f $basedir/flag");
}

# Start the stream server.
$pid = server_start( "-t test_unix_server_t", "-a stream test_server_sock" );

# Verify that stream client can connectto server.
$result = system
"runcon -t test_unix_stream_client_t $basedir/client -a stream test_client_sock test_server_sock";
ok( $result, 0 );

# Verify that dgram client cannot connectto to server.
$result = system
"runcon -t test_unix_dgram_client_t -- $basedir/client -a stream test_client_sock test_server_sock 2>&1";
ok($result);

# Kill the server.
server_end($pid);

# Start the dgram server.
$pid = server_start( "-t test_unix_server_t", "-a dgram test_server_sock" );

# Verify that dgram client can sendto server.
$result = system
"runcon -t test_unix_dgram_client_t $basedir/client -a dgram test_client_sock test_server_sock";
ok( $result, 0 );

# Verify that stream client cannot sendto server.
$result = system
"runcon -t test_unix_stream_client_t -- $basedir/client -a dgram test_client_sock test_server_sock 2>&1";
ok($result);

# Kill the server.
server_end($pid);

#
# Tests for sockets in the file namespace.
#

# Start the stream server.
$pid =
  server_start( "-t test_unix_server_t", "stream $basedir/test_server_sock" );

# Verify that stream client can connectto server.
$result = system
"runcon -t test_unix_stream_client_t $basedir/client stream $basedir/test_client_sock $basedir/test_server_sock";
ok( $result, 0 );

# Verify that dgram client cannot connectto to server.
$result = system
"runcon -t test_unix_dgram_client_t -- $basedir/client stream $basedir/test_client_sock $basedir/test_server_sock 2>&1";
ok($result);

# Kill the server.
server_end($pid);

# Start the dgram server.
$pid =
  server_start( "-t test_unix_server_t", "dgram $basedir/test_server_sock" );

# Verify that dgram client can sendto server.
$result = system
"runcon -t test_unix_dgram_client_t $basedir/client dgram $basedir/test_client_sock $basedir/test_server_sock";
ok( $result, 0 );

# Verify that stream client cannot sendto server.
$result = system
"runcon -t test_unix_stream_client_t -- $basedir/client dgram $basedir/test_client_sock $basedir/test_server_sock 2>&1";
ok($result);

# Kill the server.
server_end($pid);

# Clean up.
system "rm -f $basedir/test_client_sock $basedir/test_server_sock";

if ($socketpair) {
    #### Test SO_PEERSEC for sockets created by socketpair(2) #####
    $result = system "runcon -t test_socketpair_t $basedir/socketpair stream";
    ok( $result, 0 );

    $result = system "runcon -t test_socketpair_t $basedir/socketpair dgram";
    ok( $result, 0 );
}

exit;
